package com.chuanyun.wechatcheckin.controller;

import com.chuanyun.wechatcheckin.service.CheckinDataSyncService;
import com.chuanyun.wechatcheckin.service.BalanceLeaveProcessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.Instant;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 自动化任务控制器
 * 提供定时任务功能，自动执行同步今天打卡数据和处理调休申请数据
 */
@Slf4j
@RestController
@RequestMapping("/api/auto-task")
@RequiredArgsConstructor
public class AutoTaskController {

    private final CheckinDataSyncService checkinDataSyncService;
    private final BalanceLeaveProcessService balanceLeaveProcessService;
    
    // 任务执行状态跟踪
    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    private final AtomicLong lastExecutionTime = new AtomicLong(0);
    private final AtomicLong executionCount = new AtomicLong(0);
    private volatile String lastExecutionResult = "未执行";
    private volatile String lastErrorMessage = null;

    /**
     * 自动化任务定时执行 - 每10分钟执行一次
     * 执行顺序：1. 同步7天内的打卡数据  2. 处理调休申请数据
     */
    @Scheduled(fixedRate = 600000) // 600000毫秒 = 10分钟
    public void executeAutoTasks() {
        // 防止重复执行
        if (!isRunning.compareAndSet(false, true)) {
            log.warn("自动化任务正在执行中，跳过本次执行");
            return;
        }

        long startTime = System.currentTimeMillis();
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        long currentExecutionCount = executionCount.incrementAndGet();
        
        log.info("========== 开始执行自动化任务 (第{}次) - {} ==========", currentExecutionCount, currentTime);
        
        try {
            StringBuilder resultBuilder = new StringBuilder();
            boolean overallSuccess = true;
            
            // 任务1：同步7天内的打卡数据
            log.info("--- 任务1：同步7天内的打卡数据 ---");
            try {
                // 获取当前精确时间，并计算日期范围
                LocalDateTime currentDateTime = LocalDateTime.now();
                LocalDate endDate = currentDateTime.toLocalDate(); // 当前日期
                LocalDate startDate = endDate.minusDays(6); // 7天内包括今天，所以是减6天
                
                log.info("任务执行时间: {}, 同步日期范围: {} 到 {}", 
                    currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), 
                    startDate, endDate);
                
                CheckinDataSyncService.CheckinSyncResult syncResult = checkinDataSyncService.syncCheckinDataByDateRange(startDate, endDate);
                if (syncResult.isSuccess()) {
                    log.info("同步7天内打卡数据成功 ({} 到 {}) - 执行时间: {}, 用户数: {}, 打卡记录: {}, 日报数据: {}, 同步数据: {}", 
                        startDate, endDate, currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                        syncResult.getTotalUserCount(), 
                        syncResult.getCheckinRecordCount(),
                        syncResult.getDayDataCount(),
                        syncResult.getInsertedCount());
                    resultBuilder.append("✓ 同步7天内打卡数据成功 (").append(startDate).append(" 到 ").append(endDate)
                        .append(", 执行时间: ").append(currentDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"))).append(")");
                } else {
                    log.error("同步7天内打卡数据失败: {}", syncResult.getErrorMessage());
                    resultBuilder.append("✗ 同步7天内打卡数据失败: ").append(syncResult.getErrorMessage());
                    overallSuccess = false;
                }
            } catch (Exception e) {
                LocalDateTime errorTime = LocalDateTime.now();
                log.error("同步7天内打卡数据异常 - 错误时间: {}", errorTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), e);
                resultBuilder.append("✗ 同步7天内打卡数据异常: ").append(e.getMessage())
                    .append(" (错误时间: ").append(errorTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"))).append(")");
                overallSuccess = false;
            }
            
            resultBuilder.append("; ");
            
            // 任务2：处理调休申请数据
            log.info("--- 任务2：处理调休申请数据 ---");
            try {
                balanceLeaveProcessService.processBalanceLeaveApplications();
                log.info("处理调休申请数据成功");
                resultBuilder.append("✓ 处理调休申请数据成功");
            } catch (Exception e) {
                log.error("处理调休申请数据异常", e);
                resultBuilder.append("✗ 处理调休申请数据异常: ").append(e.getMessage());
                overallSuccess = false;
            }
            
            // 更新执行结果
            lastExecutionResult = resultBuilder.toString();
            lastErrorMessage = overallSuccess ? null : "部分任务执行失败";
            lastExecutionTime.set(startTime);
            
            // 记录任务执行完成时间
            LocalDateTime taskEndTime = LocalDateTime.now();
            long executionTimeMs = System.currentTimeMillis() - startTime;
            
            log.info("自动化任务执行完成 - 开始时间: {}, 结束时间: {}, 总耗时: {}ms, 执行次数: {}, 结果: {}", 
                LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                taskEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                executionTimeMs, currentExecutionCount, overallSuccess ? "成功" : "失败");
                
        } catch (Exception e) {
            log.error("自动化任务执行异常", e);
            lastExecutionResult = "执行异常: " + e.getMessage();
            lastErrorMessage = e.getMessage();
            lastExecutionTime.set(startTime);
        } finally {
            isRunning.set(false);
        }
    }

    /**
     * 手动触发自动化任务
     * @return 执行结果
     */
    @PostMapping("/execute")
    public ResponseEntity<Map<String, Object>> manualExecute() {
        log.info("收到手动触发自动化任务请求");
        
        Map<String, Object> response = new HashMap<>();
        
        if (isRunning.get()) {
            response.put("success", false);
            response.put("message", "自动化任务正在执行中，请稍后再试");
            response.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(409).body(response);
        }
        
        try {
            // 在新线程中执行任务，避免阻塞HTTP请求
            new Thread(this::executeAutoTasks).start();
            
            response.put("success", true);
            response.put("message", "自动化任务已开始执行");
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("手动触发自动化任务失败", e);
            
            response.put("success", false);
            response.put("message", "触发任务失败: " + e.getMessage());
            response.put("error", e.getClass().getSimpleName());
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 获取自动化任务状态
     * @return 任务状态信息
     */
    @GetMapping("/status")
    public ResponseEntity<Map<String, Object>> getTaskStatus() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            response.put("success", true);
            response.put("message", "自动化任务服务运行正常");
            
            // 任务状态信息
            Map<String, Object> taskInfo = new HashMap<>();
            taskInfo.put("isRunning", isRunning.get());
            taskInfo.put("executionCount", executionCount.get());
            taskInfo.put("lastExecutionTime", lastExecutionTime.get() > 0 ? 
                LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(lastExecutionTime.get()), 
                java.time.ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "未执行");
            taskInfo.put("lastExecutionResult", lastExecutionResult);
            taskInfo.put("lastErrorMessage", lastErrorMessage);
            
            // 下次执行时间（估算）
            if (lastExecutionTime.get() > 0) {
                long nextExecutionTime = lastExecutionTime.get() + 600000; // 10分钟后
                taskInfo.put("nextExecutionTime", 
                    LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(nextExecutionTime), 
                    java.time.ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            } else {
                taskInfo.put("nextExecutionTime", "待首次执行");
            }
            
            response.put("taskInfo", taskInfo);
            
            // 配置信息
            Map<String, Object> config = new HashMap<>();
            config.put("executionInterval", "10分钟");
            config.put("tasks", new String[]{"同步7天内打卡数据", "处理调休申请数据"});
            config.put("autoStart", true);
            
            response.put("config", config);
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("获取自动化任务状态失败", e);
            
            response.put("success", false);
            response.put("message", "获取状态失败: " + e.getMessage());
            response.put("error", e.getClass().getSimpleName());
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 停止自动化任务（仅用于紧急情况）
     * 注意：这只是设置标志位，正在执行的任务会继续完成
     * @return 操作结果
     */
    @PostMapping("/stop")
    public ResponseEntity<Map<String, Object>> stopTask() {
        log.info("收到停止自动化任务请求");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            boolean wasRunning = isRunning.get();
            
            response.put("success", true);
            response.put("message", wasRunning ? "已请求停止自动化任务（正在执行的任务会继续完成）" : "自动化任务当前未在执行");
            response.put("wasRunning", wasRunning);
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("停止自动化任务失败", e);
            
            response.put("success", false);
            response.put("message", "停止任务失败: " + e.getMessage());
            response.put("error", e.getClass().getSimpleName());
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.status(500).body(response);
        }
    }
}